using Infrastructure.Attribute;
using Infrastructure.Extensions;
using System.Linq.Expressions;
using Infrastructure;
using Microsoft.AspNetCore.Mvc;
using Infrastructure.Filters;
using Mapster;
using ZR.Repository;
using ZR.Service.Dev.IService;
using ZR.Model.Dev.Dto;
using ZR.Model.Dev.Entity;
using ZR.Model.Enums;

namespace ZR.Service.Dev.Service
{

    /// <summary>
    /// 系统菜单服务基类
    /// </summary>
    public class MenuServiceBase : BaseService<MenuEntity>
    {
            private async Task SetMenuIdPath(MenuEntity model)
            {
                    var paIdPath= await this.Repository.Context.Queryable<MenuEntity>()
                                    .Where(m => m.MenuId == model.ParentId)
                                    .Select(m => m.MenuIdPath).FirstAsync()??"/0/";
                    model.MenuIdPath = $"{paIdPath}{model.MenuId}/";
            }

            /// <summary>
            /// 添加系统菜单
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public virtual async Task<bool> AddMenu(MenuEntity model)
            {
                    await SetMenuIdPath(model);
                    return await Insertable(model).ExecuteCommandIdentityIntoEntityAsync();
            }

            /// <summary>
            /// 修改系统菜单
            /// </summary>
            /// <param name="model"></param>
            /// <returns></returns>
            public virtual async Task<bool> ModifyMenu(MenuEntity model)
            {
                    await SetMenuIdPath(model);
                    Expression<Func<MenuEntity, object>> upColsExpr = m => new
                    {
                            m.MenuId,
                            m.ParentId,
                            m.MenuType,
                            m.MenuName,
                            m.OrderNum,
                            m.Icon,
                            m.Query,
                            m.Visible,
                            m.IsFrame,
                            m.Path,
                            m.Component,
                            m.Status,
                            m.Perms,
                            m.MenunameKey,
                            m.RouteName,
                            m.UpdateBy,
                            m.UpdateTime,
                            m.Remark,
                            m.MenuIdPath,
                    };
                    return await UpdateAsync(model, upColsExpr);
            }

            /// <summary>
            /// 删除系统菜单
            /// </summary>
            /// <param name="ids"></param>
            /// <param name="isRealDel"></param>
            /// <returns></returns>
            public virtual async Task<bool> DeleteMenu(long[] ids, bool isRealDel = true)
            {
                    var isOk = false;
                    if (isRealDel)
                    {
                            isOk = await Deleteable().Where(m => ids.Contains(m.MenuId)).ExecuteCommandHasChangeAsync();
                    }
                    return isOk;
            }


            /// <summary>
            /// 获取系统菜单树选择列表
            /// </summary>
            /// <param name="req"></param>
            /// <returns></returns>
            public virtual async Task<List<TreeNodeInfo>> GetMenuTreeSelectList(GetMenuTreeSelectListReq req)
            {
                    var list=await Repository
                            .WhereIF(req.OnlyLevel1Node,m=>m.ParentId==0)
                            .Select(m => new TreeNodeInfo
                            {
                                    Id = m.MenuId.ToString(),
                                    PaId = m.ParentId.ToString(),
                                    Label=m.MenuName
                            })
                            .ToListAsync();
                    if (req.IsReturnRoot)
                    {
                            list.Add(new TreeNodeInfo
                            {
                                    Id = "0",
                                    Label = string.IsNullOrWhiteSpace(req.RootNodeName)?"所有系统菜单":req.RootNodeName,
                                    PaId = "-1"
                            });
                    }
                    var treeList=BuildTree(list);
                    return treeList;
            }
            /// <summary>
            /// 获取系统菜单分页列表
            /// </summary>
            /// <param name="req"></param>
            /// <returns></returns>
            public virtual async Task<PagedInfo<MenuListItemDto>> GetMenuPageList(GetMenuPageListReq req)
            {
                    string pathStr=null;
                    if(req.TreeNodeId>=0)
                    {
                            pathStr= $"/{req.TreeNodeId}/";
                    }
                    var filterExp=PageListFilterExp(req);
                
                    var result = await Repository.Context.Queryable<MenuEntity>()
                                .LeftJoin<MenuEntity>((m,n)=>m.ParentId==n.MenuId)
                                .Where(filterExp.ToExpression())
                                .WhereIF(req.TreeNodeId>=0,(m,n)=>m.MenuIdPath.Contains(pathStr))
                                .WhereIF(!string.IsNullOrEmpty(req.Keywords), 
                                    m => 
                                        m.MenuName.Contains(req.Keywords)
                                )
                                .OrderBy(m=>m.MenuId,OrderByType.Desc)
                    
                                .Select((m,n)=>new MenuListItemDto
                                {
                                        MenuId=m.MenuId,
                                        ParentId=m.ParentId,
                                        PaMenuName=n.MenuName,
                                        MenuType=m.MenuType,
                                        MenuName=m.MenuName,
                                        OrderNum=m.OrderNum,
                                        Query=m.Query,
                                        Visible=m.Visible,
                                        IsFrame=m.IsFrame,
                                        Path=m.Path,
                                        Component=m.Component,
                                        Status=m.Status,
                                        Perms=m.Perms,
                                        MenunameKey=m.MenunameKey,
                                        RouteName=m.RouteName,
                                })
                    .ToPageAsync(req);
                    return result;
        }

        /// <summary>
        /// 分页列表过滤表达式
        /// </summary>
        /// <param name="req"></param>
        /// <returns></returns>
        private static Expressionable<MenuEntity> PageListFilterExp(GetMenuPageListReq req)
        {
                var predicate = Expressionable.Create<MenuEntity>();

                return predicate;
        }

        /// <summary>
        /// 获取系统菜单详情
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public virtual async Task<MenuDetailDto> GetMenuDetail(long id)
        {
                var detail = await Queryable()
                    .Where(x => x.MenuId == id)
                    .FirstAsync();
                var result = detail.Adapt<MenuDetailDto>();
                return result;
        }

    }
}